package com.neusoft.neuiotms.dcom.service.impl;

import java.util.List;

import javax.persistence.EntityNotFoundException;

import org.activiti.editor.language.json.converter.util.CollectionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.neuiotms.dcom.converter.OperationGroupConverter;
import com.neusoft.neuiotms.dcom.dto.OperationGroupDTO;
import com.neusoft.neuiotms.dcom.model.Institutions;
import com.neusoft.neuiotms.dcom.model.OperationGroup;
import com.neusoft.neuiotms.dcom.repository.InstitutionsRepository;
import com.neusoft.neuiotms.dcom.repository.OperationGroupRepository;
import com.neusoft.neuiotms.dcom.service.OperationGroupService;

import io.micrometer.core.instrument.util.StringUtils;

@Service
public class OperationGroupServiceImpl implements OperationGroupService {

    @Autowired
    private OperationGroupConverter operationGroupConverter;
    @Autowired
    private OperationGroupRepository operationGroupRepository;
    @Autowired
    private InstitutionsRepository institutionsRepository;

    @Override
    public List<OperationGroupDTO> index(final Searchable searchable) {
        final List<OperationGroup> result = this.operationGroupRepository.index(searchable);
        return this.operationGroupConverter.toListDTO(result);
    }

    @Override
    public Page<OperationGroupDTO> page(final Searchable searchable, final Pageable pageable) {
        final Page<OperationGroup> result = this.operationGroupRepository.search(pageable, searchable);
        return this.operationGroupConverter.toPageDTO(result);
    }

    @Override
    public OperationGroupDTO create(final OperationGroupDTO dto) {

        final StringBuffer sb = new StringBuffer();

        if (StringUtils.isNotEmpty(dto.getGroupLeaderCode())) {
            if (null != this.operationGroupRepository.findByGroupLeaderCode(dto.getGroupLeaderCode())) {
                sb.append("一个人只能担当一个小组的组长！");
            }
        }

        // 校验一个单位只能属于一个小组
        if (null != dto.getInstitutions()) {
            dto.getInstitutions().forEach(l -> {
                final Searchable searchable = new Searchable();
                searchable.put("institutionsCode", l);
                final List<OperationGroup> checkList = this.operationGroupRepository.index(searchable);
                if (CollectionUtils.isNotEmpty(checkList)) {
                    final Institutions institutions = this.institutionsRepository.findByCode(l);
                    sb.append((institutions != null ? institutions.getName()
                            : "有些") + "单位已经属于" + checkList.get(0).getName() + "了" + "\n");
                }
            });
        }

        if (StringUtils.isNotEmpty(sb.toString())) {
            throw new UnitedException(sb.toString());
        }

        OperationGroup model = this.operationGroupConverter.toModel(dto);
        model = this.operationGroupRepository.save(model);
        return this.operationGroupConverter.toDTO(model);
    }

    @Override
    public OperationGroupDTO update(final Long id, final OperationGroupDTO dto) {

        OperationGroup model;
        try {
            model = this.operationGroupRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        final StringBuffer sb = new StringBuffer();

        if (StringUtils.isNotEmpty(dto.getGroupLeaderCode())) {
            final OperationGroup group = this.operationGroupRepository.findByGroupLeaderCode(dto.getGroupLeaderCode());
            if ((null != group) && (group.getId() != id)) {
                sb.append("一个人只能担当一个小组的组长！");
            }
        }

        // 校验一个单位只能属于一个小组
        if (null != dto.getInstitutions()) {
            dto.getInstitutions().forEach(l -> {
                final Searchable searchable = new Searchable();
                searchable.put("institutionsCode", l);
                final List<OperationGroup> checkList = this.operationGroupRepository.index(searchable);
                if (CollectionUtils.isNotEmpty(checkList)
                        && (Long.valueOf(checkList.get(0).getId()) != Long.valueOf(id))) {
                    final Institutions institutions = this.institutionsRepository.findByCode(l);
                    sb.append((institutions != null ? institutions.getName()
                            : "有些") + "单位已经属于" + checkList.get(0).getName() + "了" + "\n");
                }
            });
        }

        if (StringUtils.isNotEmpty(sb.toString())) {
            throw new UnitedException(sb.toString());
        }

        dto.setId(model.getId());
        model = this.operationGroupConverter.toModel(dto);
        this.operationGroupRepository.save(model);

        return this.operationGroupConverter.toDTO(model);
    }

    @Override
    public OperationGroupDTO detail(final String id) {

        OperationGroup model;
        try {
            if (NumberUtils.isCreatable(id)) {
                model = this.operationGroupRepository.getOne(Long.valueOf(id));
            } else {
                model = this.operationGroupRepository.findByCode(id);
            }
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        return this.operationGroupConverter.toDTO(model);
    }

    @Override
    public void delete(final Long id) {

        this.operationGroupRepository.deleteById(id);

    }

}
